package es.uned.etsii.si3.taller.servlets;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.opensymphony.xwork2.ActionSupport;

import es.uned.etsii.si3.taller.EmpleadoTaller;
import es.uned.etsii.si3.taller.FactoriaDAO;
import es.uned.etsii.si3.taller.FactoriaFunciones;
import es.uned.etsii.si3.taller.ParteTrabajo;
import es.uned.etsii.si3.taller.Reparacion;
import es.uned.etsii.si3.taller.Trabajo;
import es.uned.etsii.si3.taller.Usuario;
import es.uned.etsii.si3.taller.misc.ProporcionaFuncionalidad;

public class JSReparacionesVB extends ActionSupport implements SessionAware {

	private static final long serialVersionUID = 1L;

	private  	Map<String, Object>		userSession;
	
	private		EmpleadoTaller			datosEmpleado;
	public		EmpleadoTaller			getDatosEmpleado()							{ return this.datosEmpleado; }
	//private		void					setDatosEmpleado(EmpleadoTaller eT)			{ this.datosEmpleado = eT; }
	public		void 					setDatosEmpleado(Usuario uS) throws SQLException {
		QueryBuilder<EmpleadoTaller, Integer> eTQb;
		eTQb = FactoriaDAO.getDao(EmpleadoTaller.class).queryBuilder();
		Where<EmpleadoTaller, Integer> wETQb = eTQb.where();			
		wETQb.eq(EmpleadoTaller.ID_USUARIO_FIELD_NAME, uS);			
		List<EmpleadoTaller> lista = wETQb.query();
		this.datosEmpleado = lista.get(0);
	}
	
	
	private 	ParteTrabajo			parteSeleccionado = null;
	public 		ParteTrabajo			getParteSeleccionado() 						{ return this.parteSeleccionado; }
	public 		void					setParteSeleccionado(ParteTrabajo pT) 		{ this.parteSeleccionado = pT; }

	private 	static int 				parteSeleccionadoID = -1;
	public 		int						getParteSeleccionadoID() 					{ return JSReparacionesVB.parteSeleccionadoID; }
	public 		void					setParteSeleccionadoID(int i) 				{ JSReparacionesVB.parteSeleccionadoID = i; }
	
	private 	Reparacion				reparacionSeleccionado = null;
	public 		Reparacion				getReparacionSeleccionado()					{ return this.reparacionSeleccionado; }
	public 		void					setReparacionSeleccionado(Reparacion r)		{ this.reparacionSeleccionado = r; }

	private 	static int 				reparacionSeleccionadoID = -1;
	public 		int						getReparacionSeleccionadoID() 				{ return JSReparacionesVB.reparacionSeleccionadoID; }
	public 		void					setReparacionSeleccionadoID(int i) 			{ JSReparacionesVB.reparacionSeleccionadoID = i; }
	
	private 	Trabajo					trabajoSeleccionado = null;
	public 		Trabajo					getTrabajoSeleccionado()					{ return this.trabajoSeleccionado; }
	public 		void					setTrabajoSeleccionado(Trabajo t)			{ this.trabajoSeleccionado = t; }

	private 	static int 				trabajoSeleccionadoID = -1;
	public 		int						getTrabajoSeleccionadoID() 					{ return JSReparacionesVB.trabajoSeleccionadoID; }
	public 		void					setTrabajoSeleccionadoID(int i) 			{ JSReparacionesVB.trabajoSeleccionadoID = i; }

	private 	List<Reparacion>		listaReparaciones;
	public		List<Reparacion>		getListaReparaciones()						{ return this.listaReparaciones; }
	public		void					setListaReparaciones(List<Reparacion> l)	{ this.listaReparaciones = l; }
	
	private 	List<Trabajo>			listaTrabajos;
	public		List<Trabajo>			getListaTrabajos()							{ return this.listaTrabajos; }
	public		void					setListaTrabajos(List<Trabajo> l)			{ this.listaTrabajos = l; }

	private 	String					fechaFinString;
	public		String					getFechaFinString()							{ return this.fechaFinString; }
	public		void					setFechaFinString(String s)					{ this.fechaFinString = s; }
	
	private 	int						ambitoVB;
	public		int						getAmbitoVB()								{ return this.ambitoVB; }
	public		void					setAmbitoVB(int i)							{ this.ambitoVB = i; }
	private		static int				UNO = 1;
	private		static int				TODO = 2;	
	
	
	public JSReparacionesVB() {
		super();
		this.listaReparaciones = new ArrayList<Reparacion>();
	}

	/**
	 * Carga los trabajos pendientes de visto bueno por el jefe de sección
	 * 
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_LISTAR_PENDIENTE_VB)
	public String cargarPendientesVB() throws SQLException {
		String res = SUCCESS;		
		QueryBuilder<Reparacion, Integer> reparacionQb = this.getReparacionesPendientes();		

 		List<Reparacion> lRep = reparacionQb.query();
		List<Trabajo> lTra = new ArrayList<Trabajo>();
		QueryBuilder<Trabajo, Integer> trabajoQb;
		//sólo carga los trabajos terminados sin visto bueno
		for (int i=0; i<reparacionQb.query().size(); i++) {
			trabajoQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
			trabajoQb.where().not().isNull(Trabajo.FECHAFIN_FIELD_NAME)
			.and().eq(Trabajo.VISTOBUENOJS_FIELD_NAME, false);
			lTra = trabajoQb.query();
			if ( lTra.size() < 1 ) {
				lRep.add(reparacionQb.query().get(i));
			}
		}
		this.setListaReparaciones(lRep);
		this.setListaReparaciones(reparacionQb.query());
		return res;
	}
	
	
	private QueryBuilder<Reparacion, Integer> getReparacionesPendientes() throws SQLException {
		QueryBuilder<Reparacion, Integer> res = null;
		
		QueryBuilder<ParteTrabajo, Integer> parteQb = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();
		Where<ParteTrabajo, Integer> wParteQb = parteQb.where();
		wParteQb.eq(ParteTrabajo.ID_TALLER_FIELD_NAME, this.getDatosEmpleado().getTaller());
		wParteQb.and().eq(ParteTrabajo.VISTOBUENO_FIELD_NAME, false);		

		QueryBuilder<Reparacion, Integer> reparacionQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
		Where<Reparacion, Integer> wReparacionQb = reparacionQb.where();		
		wReparacionQb.eq(Reparacion.VISTOBUENO_FIELD_NAME, false);
		wReparacionQb.and().eq(Reparacion.ID_SECCION_FIELD_NAME, this.getDatosEmpleado().getSeccion());
		wReparacionQb.and().isNotNull(Reparacion.FECHAENTRADA_FIELD_NAME);

		QueryBuilder<Reparacion, Integer> repJOINpar = reparacionQb.join(parteQb);
		res = repJOINpar;		
		return res;
	}
	
	
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_DETALLES_PENDIENTE_VB)
	public String cargarTrabajos() throws SQLException {
		String res = SUCCESS;
		this.setReparacionSeleccionadoID(this.getReparacionSeleccionadoID());
		this.setReparacionSeleccionado(FactoriaDAO.recuperar(Reparacion.class, this.getReparacionSeleccionadoID()));
		QueryBuilder<Trabajo, Integer> trabajoQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
		Where<Trabajo, Integer> wTrabajoQb = trabajoQb.where();		
		wTrabajoQb.eq(Trabajo.ID_REPARACION_FIELD_NAME, this.getReparacionSeleccionado());
		this.setListaTrabajos(trabajoQb.query());
		return res;
	}
	
	/**
	 * Rechaza un trabajo de un mecánico
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_RECHAZAR_PENDIENTE_VB)
	public String trabajoRechazar() throws SQLException {
		String res = SUCCESS;
		this.setTrabajoSeleccionadoID(this.getTrabajoSeleccionadoID());
		this.setTrabajoSeleccionado(FactoriaDAO.recuperar(Trabajo.class, this.getTrabajoSeleccionadoID()));
		this.getTrabajoSeleccionado().setFechaFin(null);
		this.getTrabajoSeleccionado().setVistoBuenoJS(false);
		this.getTrabajoSeleccionado().update();
		return res;
	}

	/**
	 * Le da el visto bueno a un trabajo
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_ACEPTAR_PENDIENTE_VB)
	public String trabajoAceptar() throws SQLException {
		String res = SUCCESS;
		this.setTrabajoSeleccionadoID(this.getTrabajoSeleccionadoID());
		this.setTrabajoSeleccionado(FactoriaDAO.recuperar(Trabajo.class, this.getTrabajoSeleccionadoID()));
		if ( this.getFechaFinString().isEmpty() ) {			
			addActionError("La fecha de visto bueno es obligatoria");
			res = ERROR;
		} else {
			SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy");
			Date fechaFin = null;
			try {
				fechaFin = df.parse(this.getFechaFinString());
				this.getTrabajoSeleccionado().setFechaFin(fechaFin);
			} catch (ParseException e) {
				addActionError("Formato de la fecha erróneo");
				res = ERROR;
			}
			this.getTrabajoSeleccionado().setVistoBuenoJS(true);
			this.getTrabajoSeleccionado().update();
			if ( existenPendientes() ) {
				this.setAmbitoVB(UNO);
			} else {
				this.setAmbitoVB(TODO);
				this.getReparacionSeleccionado().setVistoBueno(true);
				this.getReparacionSeleccionado().setFechaFin(fechaFin);				
				this.getReparacionSeleccionado().update();
			}
		}
		return res;
	}
	
	
	private boolean existenPendientes() throws SQLException {
		boolean res = true;
		this.setReparacionSeleccionado(FactoriaDAO.recuperar(Reparacion.class, this.getTrabajoSeleccionado().getReparacion().getId()));
		this.setReparacionSeleccionadoID(this.getReparacionSeleccionado().getId());
		QueryBuilder<Trabajo, Integer> trabajoQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
		Where<Trabajo, Integer> wTrabajoQb = trabajoQb.where();		
		wTrabajoQb.eq(Trabajo.ID_REPARACION_FIELD_NAME, this.getReparacionSeleccionado());
		wTrabajoQb.and().eq(Trabajo.VISTOBUENOJS_FIELD_NAME, false);
		if ( trabajoQb.query().size() < 1 ) {
			res = false;
		}
		return res;
	}
	
	
	@Override
	public void setSession(Map<String, Object> session) {
		userSession = session;
		try {
			this.setDatosEmpleado((Usuario) userSession.get("usuario"));
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	
}
